import urllib.parse
from urllib.parse import urlencode, quote

import requests
from requests.auth import HTTPBasicAuth

class Harbor_API:
    def __init__(self,host, port, username, password, ignore80=False):
        self.host = host
        self.port = port
        self.username = username
        self.password = password
        self.ignore80 = ignore80
        self.auth = HTTPBasicAuth(self.username, self.password)

    def projects(self):
        """
        获取harbor所有项目
        :return:
        """
        url = self.build_url("projects?page=1&page_size=100&width_detail=true")
        res = requests.get(f"{url}", auth=self.auth)
        return res.json()

    def project_info(self, name):
        url = self.build_url(f"projects/{str(name)}")
        print(url)
        res = requests.get(f"{url}", auth=self.auth)
        return res.json()

    def project_exists(self, name):
        """
        检查指定的项目是否存在
        :param name: 项目名称
        :return: 如果项目存在返回True，否则返回False
        """
        url = self.build_url(f"projects/{str(name)}")
        res = requests.get(f"{url}", auth=self.auth)
        if res.status_code == 200:
            return True
        else:
            return False

    def create_project(self, name, description=""):
        """
        创建指定的项目
        :param name: 项目名称
        :param description: 项目描述
        :return: 如果项目创建成功返回True，否则返回False
        """
        url = self.build_url("projects")
        data = {
            "project_name": name,
            "metadata": {
                "public": "false"
            },
            "description": description
        }
        res = requests.post(f"{url}", json=data, auth=self.auth)
        if res.status_code == 201:
            return True
        else:
            return False

    def members(self, name):
        url = self.build_url(f"projects/{str(name)}/members")
        res = requests.get(f"{url}", auth=self.auth)
        print(res)
        return res.json()

    def repos(self, name):
        url = self.build_url(f"projects/{str(name)}/repositories?page_size=100&page=1")
        res = requests.get(f"{url}", auth=self.auth)
        return list(res.json())

    def artifacts(self, project_name, repo_name):
        rn = urllib.parse.quote_plus(repo_name)
        rn = urllib.parse.quote_plus(rn)
        url = self.build_url(f"projects/{str(project_name)}/repositories/{rn}/artifacts?page_size=100&page=1")
        res = requests.get(f"{url}", auth=self.auth)
        return res.json()

    def build_url(self, path):
        if self.ignore80:
            if str(self.port) == "80":
                return f"http://{self.host}/api/v2.0/{path}"
        return f"http://{self.host}:{self.port}/api/v2.0/{path}"

    def build_image_name(self, project_name, repo_name, tag_name):
        if self.ignore80:
            if str(self.port) == "80":
                return f"{self.host}/{project_name}/{repo_name}:{tag_name}"
        return f"{self.host}:{self.port}/{project_name}/{repo_name}:{tag_name}"

    def get_all_artifacts(self, project_names=None):
        all_artifacts = []
        if project_names is None:
            pros = self.projects()
            project_names = [project["name"] for project in pros]
        
        for project_name in project_names:
            # print(f"project_name: {project_name}")
            repo_list = self.repos(project_name)
            for repo in repo_list:
                repo_name = repo["name"]
                repo_name = repo_name[len(project_name) + 1:]
                repo_name = quote(repo_name)
                # print(f"\trepo_name: {repo_name}")
                artifact_list = self.artifacts(project_name, repo_name)
                for artifact in artifact_list:
                    tags = artifact['tags']
                    if tags is not None:
                        for tag in tags:
                            tag_name = tag["name"]
                            image = self.build_image_name(project_name, repo_name, tag_name)
                            # print(f"\t\t{image}")
                            all_artifacts.append(image)
        return all_artifacts

if __name__ == '__main__':

    HARBOR_HOST = "192.168.100.10"
    HARBOR_PORT = 80
    HARBOR_USER = "admin"
    HARBOR_PASS = "Harbor12345"
    harbor_api = Harbor_API(HARBOR_HOST, HARBOR_PORT, HARBOR_USER, HARBOR_PASS, ignore80=True)
    alls = harbor_api.get_all_artifacts()
    print(alls)
